home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / source / graphicgems4.lha / GemsIV / trilerp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-06  |  2.8 KB  |  134 lines

  1. /*
  2.  * C code from the article
  3.  * "Tri-linear Interpolation"
  4.  * by Steve Hill, sah@ukc.ac.uk
  5.  * in "Graphics Gems IV", Academic Press, 1994
  6.  *
  7.  * compile with "cc -DMAIN ..." to create a test program
  8.  */
  9.  
  10. #include <math.h>
  11. #include "GraphicsGems.h"
  12.  
  13. double
  14. trilinear(p, d, xsize, ysize, zsize, def)
  15. Point3     *p;
  16. double     *d;
  17. int     xsize, ysize, zsize;
  18. double     def;
  19. {
  20. #   define DENS(X, Y, Z) d[(X)+xsize*((Y)+ysize*(Z))]
  21.  
  22.     int           x0, y0, z0,
  23.            x1, y1, z1;
  24.     double     *dp,
  25.            fx, fy, fz,
  26.            d000, d001, d010, d011,
  27.            d100, d101, d110, d111,
  28.            dx00, dx01, dx10, dx11,
  29.            dxy0, dxy1, dxyz;
  30.  
  31.     x0 = floor(p->x); fx = p->x - x0;
  32.     y0 = floor(p->y); fy = p->y - y0;
  33.     z0 = floor(p->z); fz = p->z - z0;
  34.  
  35.     x1 = x0 + 1;
  36.     y1 = y0 + 1;
  37.     z1 = z0 + 1;
  38.  
  39.     if (x0 >= 0 && x1 < xsize &&
  40.     y0 >= 0 && y1 < ysize &&
  41.     z0 >= 0 && z1 < zsize)
  42.     {
  43.     dp = &DENS(x0, y0, z0);
  44.     d000 = dp[0];
  45.     d100 = dp[1];
  46.     dp += xsize;
  47.     d010 = dp[0];
  48.     d110 = dp[1];
  49.     dp += xsize*ysize;
  50.     d011 = dp[0];
  51.     d111 = dp[1];
  52.     dp -= xsize;
  53.     d001 = dp[0];
  54.     d101 = dp[1];
  55.     }
  56.     else
  57.     {
  58. #    define INRANGE(X, Y, Z) \
  59.           ((X) >= 0 && (X) < xsize && \
  60.            (Y) >= 0 && (Y) < ysize && \
  61.            (Z) >= 0 && (Z) < zsize)
  62.  
  63.     d000 = INRANGE(x0, y0, z0) ? DENS(x0, y0, z0) : def;
  64.     d001 = INRANGE(x0, y0, z1) ? DENS(x0, y0, z1) : def;
  65.     d010 = INRANGE(x0, y1, z0) ? DENS(x0, y1, z0) : def;
  66.     d011 = INRANGE(x0, y1, z1) ? DENS(x0, y1, z1) : def;
  67.  
  68.     d100 = INRANGE(x1, y0, z0) ? DENS(x1, y0, z0) : def;
  69.     d101 = INRANGE(x1, y0, z1) ? DENS(x1, y0, z1) : def;
  70.     d110 = INRANGE(x1, y1, z0) ? DENS(x1, y1, z0) : def;
  71.     d111 = INRANGE(x1, y1, z1) ? DENS(x1, y1, z1) : def;
  72.     }
  73.  
  74.     dx00 = LERP(fx, d000, d100);
  75.     dx01 = LERP(fx, d001, d101);
  76.     dx10 = LERP(fx, d010, d110);
  77.     dx11 = LERP(fx, d011, d111);
  78.  
  79.     dxy0 = LERP(fy, dx00, dx10);
  80.     dxy1 = LERP(fy, dx01, dx11);
  81.  
  82.     dxyz = LERP(fz, dxy0, dxy1);
  83.  
  84.     return dxyz;
  85. }
  86.  
  87. #ifdef MAIN
  88.  
  89. /* test program for trilinear interpolation */
  90.  
  91. #include <stdio.h>
  92.  
  93. #define XSIZE    2
  94. #define YSIZE    2
  95. #define ZSIZE    2
  96.  
  97. main()
  98. {
  99. #define TDENS(X,Y,Z) d[(X)+XSIZE*((Y)+YSIZE*(Z))]
  100.  
  101.     extern double trilinear();
  102.     double    *d, def;
  103.     int     x, y, z;
  104.     Point3    p;
  105.  
  106.     d = (double *) malloc(sizeof(double) * XSIZE * YSIZE * ZSIZE);
  107.  
  108.     printf("Test for trilinear interpolation\n");
  109.     printf("Enter the densities for the corners of a cube\n");
  110.  
  111.     for (x = 0; x < XSIZE; x++)
  112.     for (y = 0; y < YSIZE; y++)
  113.     for (z = 0; z < ZSIZE; z++)
  114.     {
  115.         printf("Point (%d, %d, %d) is: ", x, y, z);
  116.         scanf("%lf", &TDENS(x, y, z));
  117.     }
  118.  
  119.     printf("Enter the default density: ");
  120.     scanf("%lf", &def);
  121.  
  122.     printf("Enter point of interest: ");
  123.     while (scanf("%lf %lf %lf", &p.x, &p.y, &p.z) == 3)
  124.     {
  125.         double    n;
  126.  
  127.         n = trilinear(&p, d, XSIZE, YSIZE, ZSIZE, def);
  128.         printf("Density at (%lf, %lf, %lf) is %lf\n", p.x, p.y, p.z, n);
  129.         printf("Enter point of interest: ");
  130.     }
  131. }
  132.  
  133. #endif
  134.